package com.kylin.weixin.common.xml.bean;


import com.kylin.qq.weixin.mp.aes.AesException;
import com.kylin.qq.weixin.mp.aes.WXBizMsgCrypt;
import com.kylin.weixin.common.xml.builder.outxml.ImageBuilder;
import com.kylin.weixin.common.xml.builder.outxml.NewsBuilder;
import com.kylin.weixin.common.xml.builder.outxml.TextBuilder;
import com.kylin.weixin.common.xml.utils.XStreamCDataConverter;
import com.kylin.weixin.common.xml.utils.XStreamTransformer;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

@XStreamAlias("xml")
public abstract class WeChatXmlOutMessage implements Serializable {

  private static final Logger LOGGER = LoggerFactory.getLogger(WeChatXmlOutMessage.class);

  private static final long serialVersionUID = 1291489635527589966L;
  @XStreamAlias("ToUserName")
  @XStreamConverter(value = XStreamCDataConverter.class)
  protected String toUserName;

  @XStreamAlias("FromUserName")
  @XStreamConverter(value = XStreamCDataConverter.class)
  protected String fromUserName;

  @XStreamAlias("CreateTime")
  protected Long createTime;

  @XStreamAlias("MsgType")
  @XStreamConverter(value = XStreamCDataConverter.class)
  protected String msgType;

  /**
   * 获得文本消息builder
   */
  public static TextBuilder TEXT() {
    return new TextBuilder();
  }

  /**
   * 获得图片消息builder
   */
  public static ImageBuilder IMAGE() {
    return new ImageBuilder();
  }

  /**
   * 获得图文消息builder
   */
  public static NewsBuilder NEWS() {
    return new NewsBuilder();
  }


  @SuppressWarnings("unchecked")
  public String toXml() {
    return XStreamTransformer.toXml((Class<WeChatXmlOutMessage>) this.getClass(), this);
  }

  /**
   * 转换成加密的xml格式
   */
  public String toEncryptedXml(String token, String encodingAesKey, String appId) {
    String plainXml = toXml();
    try {
      WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
      // 生成安全签名
      String timeStamp = Long.toString(System.currentTimeMillis() / 1000L);
      String nonce = pc.getRandomStr();
      return pc.encryptMsg(plainXml, timeStamp, nonce);
    } catch (AesException e) {
      LOGGER.info("xml消息加密异常：{}", e);
      return null;
    }
  }

  public String getToUserName() {
    return toUserName;
  }

  public void setToUserName(String toUserName) {
    this.toUserName = toUserName;
  }

  public String getFromUserName() {
    return fromUserName;
  }

  public void setFromUserName(String fromUserName) {
    this.fromUserName = fromUserName;
  }

  public Long getCreateTime() {
    return createTime;
  }

  public void setCreateTime(Long createTime) {
    this.createTime = createTime;
  }

  public String getMsgType() {
    return msgType;
  }

  public void setMsgType(String msgType) {
    this.msgType = msgType;
  }
}
